package com.miplus.ccrm.core.service.sto;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.miplus.ccrm.common.*;
import com.miplus.ccrm.core.controller.vo.sto.*;
import com.miplus.ccrm.core.mapper.FiCreditcasesMapper;
import com.miplus.ccrm.core.mapper.IouLoanInvoiceInfoMapper;
import com.miplus.ccrm.core.mapper.IouRepayApplyMapper;
import com.miplus.ccrm.core.mapper.model.LoanInvoiceDeductionBatchVo;
import com.miplus.ccrm.core.pojo.*;
import com.miplus.ccrm.core.service.action.SmsSendphnService;
import com.miplus.ccrm.core.service.conf.IouProductService;
import com.miplus.ccrm.core.service.crd.FiCreditcasesHistService;
import com.miplus.ccrm.core.service.cust.ConContactService;
import com.miplus.ccrm.core.service.cust.ConCustomerService;
import com.miplus.ccrm.core.utils.EnumFiCaseQueue;
import com.miplus.ccrm.core.utils.EnumFiCaseStatus;
import com.miplus.ccrm.sms.LineAPIR;
import com.miplus.ccrm.sms.OnLineApiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author： Yaohui
 * @Date： 2024/12/3 14:06
 * @Describe：
 */
@Slf4j
@Service
public class OnLineServiceImpl implements OnLineService{

    @Resource
    OnLineApiService onLineApiService;

    @Resource
    ConCustomerService conCustomerService;

    @Resource
    IouRepayApplyMapper iouRepayApplyMapper;

    @Resource
    IouLoanInvoiceInfoMapper iouLoanInvoiceInfoMapper;
    @Resource
    ConContactService conContactService;

    @Resource
    private SmsSendphnService smsSendphnService;

    @Resource
    FiCreditcasesMapper fiCreditcasesMapper;

    @Resource
    FiCreditcasesHistService fiCreditcasesHistService;

    @Resource
    IouProductService iouProductService;

    @Override
    public LineAPIR refreshSOFPCreditLimit(SOFPReqVo reqVo) {

        if(JPubUtils.IsEmpty(reqVo.getCustomernumber())
            ||JPubUtils.IsEmpty(reqVo.getProductId())  ){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());

        if(dbConCustomer==null
        || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }


        return onLineApiService.refreshSOFPCreditLimit(reqVo.getProductId(),dbConCustomer.getOpenacctcertno());
    }

    @Override
    public LineAPIR getSOFPLoanLnvoiceInfo(SOFPReqVo reqVo) {

        if(JPubUtils.IsEmpty(reqVo.getCustomernumber())
                ||JPubUtils.IsEmpty(reqVo.getCtrSeqNo())  ){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());

        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        return onLineApiService.getSOFPLoanLnvoiceInfo(reqVo.getCtrSeqNo(),dbConCustomer.getOpenacctcertno(),reqVo.getStatus());
    }

    @Override
    public LineAPIR getSOFPRepayPlan(SOFPReqVo reqVo) {

        if(JPubUtils.IsEmpty(reqVo.getLoanDblNo())
                ||JPubUtils.IsEmpty(reqVo.getCustomernumber())  ){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }
        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }
        return onLineApiService.getSOFPRepayPlan(reqVo.getLoanDblNo(),dbConCustomer.getOpenacctcertno());
    }

    @Override
    public LineAPIR getSOFPRepaySerial(SOFPReqVo reqVo) {

        if(JPubUtils.IsEmpty(reqVo.getLoanDblNo())
                ||JPubUtils.IsEmpty(reqVo.getCustomernumber())  ){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        return onLineApiService.getSOFPRepaySerial(reqVo.getLoanDblNo(),dbConCustomer.getOpenacctcertno());
    }

    @Override
    public LineAPIR getSOFPTrial(SOFPReqVo reqVo) {

        if(JPubUtils.IsEmpty(reqVo.getLoanDblNo())
                ||JPubUtils.IsEmpty(reqVo.getTrialTp())  ){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        return onLineApiService.getSOFPTrial(reqVo.getLoanDblNo(),reqVo.getTrialTp());
    }

    @Override
    public LineAPIR getSOFPRepaymentResult(SOFPReqVo reqVo) {

        if(JPubUtils.IsEmpty(reqVo.getCustomernumber())
                ||JPubUtils.IsEmpty(reqVo.getLoanDblNo())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        return onLineApiService.getSOFPRepaymentResult(null,
                reqVo.getLoanDblNo(),dbConCustomer.getOpenacctcertno() );
    }

    @Override
    @Transactional
    public CmdResVo repaymentApply(JSysUser user, RepayApplyReqVo reqVo) {

        List<IouProduct> productList = iouProductService.query()
                .eq("product_id", reqVo.getProductId()).list();

        if(productList!=null && productList.size()>0){
            if(JPubUtils.IsNotEmpty(productList.get(0).getParentId())){
                log.info("parentId:{}",productList.get(0).getParentId());
                reqVo.setProductId(productList.get(0).getParentId());
            }
        }

        Date currentDate =new Date();
        if(1==reqVo.getApplyType()){
            return clmp(user,currentDate,reqVo);
        }else if(2==reqVo.getApplyType()){
            return sofp(user,currentDate,reqVo);
        }
        return new CmdResVo();
    }

    @Override
    public List<RepayApplyResVo> repayApplyList(String creditcaseid,String type) {

        List<RepayApplyResVo> dbRepayApplyList= iouRepayApplyMapper.selectJoinList(
                RepayApplyResVo.class,new MPJLambdaWrapper<IouRepayApply>()
                .eq("creditcaseid", creditcaseid)
                .eq("apply_type", type)
        );


        if(dbRepayApplyList==null
            || dbRepayApplyList.size()==0){
            throw new ServiceException(EnumRCode.NoData.value, EnumRCode.NoData.name);
        }

        for (int i = 0; i < dbRepayApplyList.size(); i++) {
            IouRepayApply iouRepayApply=new IouRepayApply();
            RepayApplyResVo repayApplyResVo = dbRepayApplyList.get(i);
            iouRepayApply.setRepayApplyId(repayApplyResVo.getRepayApplyId());

            repayApplyResVo.setApplyTypeDesc(repayApplyResVo.getApplyType()==1?"融资中台":"智慧线上");
            repayApplyResVo.setTypeDesc(repayApplyResVo.getType()==1?"一键扣款":"支付宝");

            if(1==repayApplyResVo.getApplyType()){

                //融资中台
                LineAPIR clmpRepaymentResult = onLineApiService.getCLMPRepaymentResult(repayApplyResVo.getMerchantId(),
                        String.valueOf(repayApplyResVo.getRepayApplyId()));
                if(clmpRepaymentResult.getCode()==0){
                    // 实还金额 本、利、罚
                    String repymtSt = clmpRepaymentResult.getJsonObject().get("RepymtSt").toString();
                    repayApplyResVo.setResult(clmpRepaymentResultDesc(repymtSt));
                    repayApplyResVo.setLastRepayAmt(clmpRepaymentResult.getJsonObject().get("ActRepymtAmt").toString());
                    repayApplyResVo.setRepymtPnp(clmpRepaymentResult.getJsonObject().get("ActRepymtPnp").toString());
                    repayApplyResVo.setRepymtInt(clmpRepaymentResult.getJsonObject().get("ActRepymtInt").toString());
                    repayApplyResVo.setRepymtPnltyInt(clmpRepaymentResult.getJsonObject().get("ActRepymtPnltyInt").toString());

                    log.info("repymtSt:{}",repymtSt);
                    if("1".equals(repymtSt)){//还款成功
                        iouRepayApply.setStatus("2");
                    } else if ("2".equals(repymtSt)) {
                        iouRepayApply.setStatus("1");
                    } else {
                        iouRepayApply.setStatus(repymtSt);
                    }

                    iouRepayApplyMapper.updateById(iouRepayApply);
                }

            } else if (2==repayApplyResVo.getApplyType()) {

                // 智慧线上
                LineAPIR sofpRepaymentResult = onLineApiService.getSOFPRepaymentResult(String.valueOf(repayApplyResVo.getRepayApplyId()),
                        repayApplyResVo.getLoanInvoiceId(), repayApplyResVo.getIdnumber());
                if(sofpRepaymentResult.getCode()==0){
                    // 实还金额 本、利、罚
                    String repymtSt = sofpRepaymentResult.getJsonObject().get("RepymtSt").toString();
                    repayApplyResVo.setResult(sofpRepaymentResultDesc(repymtSt));
                    repayApplyResVo.setLastRepayAmt(sofpRepaymentResult.getJsonObject().get("ActRepymtTotAmt").toString());
                    repayApplyResVo.setRepymtPnp(sofpRepaymentResult.getJsonObject().get("ActRepyPnpAmt").toString());
                    repayApplyResVo.setRepymtInt(sofpRepaymentResult.getJsonObject().get("ActRepyInt").toString());
                    repayApplyResVo.setRepymtPnltyInt(sofpRepaymentResult.getJsonObject().get("ActRepyPnyInt").toString());


                    iouRepayApply.setStatus(repymtSt);
                    iouRepayApplyMapper.updateById(iouRepayApply);
                }
            }

        }

        return dbRepayApplyList;

    }


    public String clmpRepaymentResultDesc(String result){
        switch (result){
            case "0":
                return "初始化";
            case "1":
                return "还款成功";
            case "2":
                return "还款中";
            case "3":
                return "还款失败";
        }

        return null;
    }
    public String sofpRepaymentResultDesc(String result){
        switch (result){

            case "1":
                return "处理中";
            case "2":
                return "还款成功";
            case "3":
                return "还款失败";
        }

        return null;
    }


    public CmdResVo sofp(JSysUser user,Date currentDate,RepayApplyReqVo reqVo){
        String df= new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(currentDate);// 时间格式 2024/07/18 12:00

        // 智慧线上还款申请

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());

        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        //生成申请流水号
        IouRepayApply repayApply=new IouRepayApply();
        repayApply.setCreditcaseid(reqVo.getCreditcaseid());
        repayApply.setApplyType(reqVo.getApplyType());
        repayApply.setType(Integer.valueOf(reqVo.getType()));
        repayApply.setLoanInvoiceId(reqVo.getLoanInvoiceId());
        repayApply.setBorrowerUserId(reqVo.getCustomernumber());
        repayApply.setProductId(reqVo.getProductId());
        repayApply.setCurrentNum(reqVo.getCurrentNum());
        repayApply.setStatus("0");
        repayApply.setIdnumber(dbConCustomer.getOpenacctcertno());
        repayApply.setRepayAmt(new BigDecimal(reqVo.getRepymtAmt1()));
        repayApply.setCreateTime(currentDate);
        repayApply.setOperatorId(user.getUsrid());
        repayApply.setOperatorName(user.getName());
        ConContact dbContact=null;
        if("1".equals(reqVo.getType())){

            int i = iouRepayApplyMapper.insert(repayApply);

            //还款流水号
            log.info("智慧线上还款申请->还款流水号：{}",repayApply.getRepayApplyId());

            LineAPIR lineAPIR = onLineApiService.SOFPRepaymentApplyDeduction(
                    String.valueOf(repayApply.getRepayApplyId()),
                    reqVo.getLoanInvoiceId(),
                    dbConCustomer.getOpenacctcertno(),
                    null,
                    reqVo.getRepymtAmt1(),
                    String.valueOf(reqVo.getCurrentNum()),
                    df
            );
            if(lineAPIR.getCode()!=0){

                throw new ServiceException(EnumRCode.FeignErr.value, lineAPIR.getMessage());
            }


        } else if ("2".equals(reqVo.getType())) {


            //获取联系人手机号
            if(JPubUtils.IsEmpty(reqVo.getContactnumber())){
                throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
            }

            dbContact = conContactService.getById(reqVo.getContactnumber());
            if(dbContact==null){
                throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
            }

            repayApply.setPhone(dbContact.getPhone());

            int i = iouRepayApplyMapper.insert(repayApply);

            //还款流水号
            log.info("智慧线上还款申请->还款流水号：{}",repayApply.getRepayApplyId());

            LineAPIR lineAPIR = onLineApiService.SOFPRepaymentApplyZFB(
                    String.valueOf(repayApply.getRepayApplyId()),
                    reqVo.getLoanInvoiceId(),
                    reqVo.getProductId(),
                    reqVo.getRepymtAmt1(),
                    String.valueOf(reqVo.getCurrentNum()),
                    df
            );

            if(lineAPIR.getCode()!=0){

                throw new ServiceException(EnumRCode.FeignErr.value, lineAPIR.getMessage());
            }

            String url = lineAPIR.getJsonObject().get("ShrtMsgSrlNo").toString();
            log.info("智慧线上还款申请支付宝URL:{}",url);
            if(JPubUtils.IsNotEmpty(url)){
                try {
                    // 短信发送
                    smsSendphnService.repayApplySms(String.valueOf(reqVo.getCreditcaseid()),
                            user.getUsrid(),Long.valueOf(dbContact.getContactnumber()),
                            repayApply.getPhone(),dbConCustomer.getCustenname(),
                            dbConCustomer.getGender(),
                            reqVo.getRepymtAmt1(),
                            url);
                } catch (Exception e) {
                    return new CmdResVo(-1,"扣款申请成功,短信发送失败!");
                }
            }

        }

        return new CmdResVo(1,repayApply.getRepayApplyId().toString());
    }


    public CmdResVo clmp(JSysUser user, Date currentDate, RepayApplyReqVo reqVo){


        IouLoanInvoiceInfo dBLoanInvoiceInfo = iouLoanInvoiceInfoMapper.getDblNo(reqVo.getLoanInvoiceId());
//        if(dBLoanInvoiceInfo==null || JPubUtils.IsEmpty(dBLoanInvoiceInfo.getMerchantId())){
//            log.error("reqVo.getDblNo():{}",reqVo.getLoanInvoiceId());
//            throw new ServiceException(EnumRCode.TooManyRequest.value, EnumRCode.TooManyRequest.name);
//        }

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());

        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        //生成申请流水号
        IouRepayApply repayApply=new IouRepayApply();
        repayApply.setCreditcaseid(reqVo.getCreditcaseid());
        repayApply.setApplyType(reqVo.getApplyType());
        repayApply.setType(Integer.valueOf(reqVo.getType()));
        repayApply.setLoanInvoiceId(reqVo.getLoanInvoiceId());
        repayApply.setBorrowerUserId(reqVo.getCustomernumber());
        repayApply.setProductId(reqVo.getProductId());
        repayApply.setMerchantId(dBLoanInvoiceInfo.getMerchantId());
        repayApply.setStatus("0");
        repayApply.setIdnumber(dbConCustomer.getOpenacctcertno());
        repayApply.setRepayAmt(new BigDecimal(reqVo.getRepymtAmt1()));
        repayApply.setCreateTime(currentDate);
        repayApply.setOperatorId(user.getUsrid());
        repayApply.setOperatorName(user.getName());

        ConContact dbContact=null;
        //获取扣款方式
        if("2".equals(reqVo.getType())){
            //获取联系人手机号
            if(JPubUtils.IsEmpty(reqVo.getContactnumber())){
                throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
            }
             dbContact = conContactService.getById(reqVo.getContactnumber());
            if(dbContact==null){
                throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
            }
            repayApply.setPhone(dbContact.getPhone());
        }


        int i = iouRepayApplyMapper.insert(repayApply);

        //还款流水号
        log.info("融资中台还款申请->还款流水号：{}",repayApply.getRepayApplyId());

        String type=reqVo.getType();

        if(type.equals("1")){
            type="01";//01-借款人还款=归还欠款
        }
        if(type.equals("2")){//支付宝还款方式
            type="04";//因为请求的时候 还款方式对方定义支付宝为04
        }

        LineAPIR lineAPIR = onLineApiService.CLMPRepaymentApply(
                null,
                dbConCustomer.getOpenacctcertno(),
                reqVo.getLoanInvoiceId(),
                new BigDecimal(reqVo.getRepymtAmt1()),
                type,
                String.valueOf(repayApply.getRepayApplyId())
        );


        if(lineAPIR.getCode()!=0){

            throw new ServiceException(EnumRCode.TooManyRequest.value, lineAPIR.getMessage());
        }

        String url = lineAPIR.getJsonObject().get("MsgUrl").toString();
        log.info("融资中台还款申请支付宝URL:{}",url);
        if(JPubUtils.IsNotEmpty(url)){
            try {
                //短信发送
                smsSendphnService.repayApplySms(String.valueOf(reqVo.getCreditcaseid()),
                        user.getUsrid(),Long.valueOf(dbContact.getContactnumber()),repayApply.getPhone(),dbConCustomer.getCustenname(),
                        dbConCustomer.getGender(),
                        reqVo.getRepymtAmt1(),
                        url);
            } catch (Exception e) {
               return new CmdResVo(-1,"扣款申请成功,短信发送失败!");
            }
        }

        return new CmdResVo(1,repayApply.getRepayApplyId().toString());
    }

    @Override
    public OnLineResVo repaymentVerification(OnLineReqVo reqVo) {
        OnLineResVo resVo = new OnLineResVo();
        if("1".equals(reqVo.getType())){



            //获取 客户证件号
            ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
            if(dbConCustomer==null
                    || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())
                    || JPubUtils.IsEmpty(reqVo.getProductId())){
                throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
            }

            List<IouProduct> productList = iouProductService.query()
                    .eq("product_id", reqVo.getProductId()).list();

            if(productList!=null && productList.size()>0){
                if(JPubUtils.IsNotEmpty(productList.get(0).getParentId())){
                    log.info("parentId:{}",productList.get(0).getParentId());
                    reqVo.setProductId(productList.get(0).getParentId());
                }
            }


            //融资中台
            LineAPIR clmpLoanLnvoiceInfo = onLineApiService.getCLMPLoanLnvoiceInfo(null
                    , dbConCustomer.getOpenacctcertno()
                    , dbConCustomer.getOpenacctcerttype(),
                    reqVo.getLoanInvoiceId(),0,reqVo.getProductId());


            JSONArray dblInfArry = clmpLoanLnvoiceInfo.getJsonObject().getJSONArray("DblInfArry");
            if(dblInfArry==null||JPubUtils.IsEmpty(dblInfArry.getJSONObject(0).get("OvrDuedPnp").toString())){
                throw new ServiceException(342, "未查询到逾期未还金额");
            }
            resVo.setAmountMax(new BigDecimal(dblInfArry.getJSONObject(0).get("OvrDuedPnp").toString()));
            resVo.setAmount(resVo.getAmountMax());
            resVo.setLoanInvoiceId(reqVo.getLoanInvoiceId());
            return resVo;
        } else if ("2".equals(reqVo.getType())) {

            //获取 客户证件号
            ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
            if(dbConCustomer==null
                    || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
                throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
            }


            //获取 智慧线上的还款计划结果

            LineAPIR sofpRepayPlan = onLineApiService.getSOFPRepayPlan(reqVo.getLoanInvoiceId(),
                    dbConCustomer.getOpenacctcertno());

            JSONArray repymtPlanArry = sofpRepayPlan.getJsonObject().getJSONArray("RepymtPlanArry");

            Integer currnumber=0;
            for (int i = 0; i < repymtPlanArry.size(); i++) {
                JSONObject jsonObject = repymtPlanArry.getJSONObject(i);
                BigDecimal remainpay = new BigDecimal(jsonObject.get("remainpay").toString());
                if(remainpay.compareTo(BigDecimal.ZERO)>0){
                    //获取 剩余金额大于0 并且最小期数的 数据
                    resVo.setCurrnumber(Integer.valueOf(jsonObject.get("TrmTms1").toString()));//期次
                    resVo.setAmountMax(remainpay);//剩余金额
                    resVo.setAmount(remainpay);

//                    if(currnumber<resVo.getCurrnumber()){
//                        currnumber=resVo.getCurrnumber();
//                        resVo.setAmount(remainpay);
//                        resVo.setAmountMax(remainpay);//剩余金额
//                    }
                }
            }
            resVo.setLoanInvoiceId(reqVo.getLoanInvoiceId());
            return resVo;
        }

        return new OnLineResVo();
    }


    @Override
    @Transactional
    public RefreshCaseBatchReqVo refreshCaseBatch(RefreshCaseBatchReqVo reqVo,String userId) {

        for (RefreshCaseBatchReqVo.BatchList refreshCaseBatchReqVo : reqVo.getList()) {

            //停催不进行查询
//            if(!(refreshCaseBatchReqVo.getCcc().equals(EnumFiCaseQueue.O.value)
//                    || refreshCaseBatchReqVo.getCcc().equals(EnumFiCaseQueue.Q.value))){
//                refreshCaseBatchReqVo.setUpdatecccdsc(fiCreditcasesMapper.getCccDesc(refreshCaseBatchReqVo.getCcc()));
//                continue;
//            }


//            fun_getnames('COLLECT.STATUS',t.status)
            CmdResVo cmdResVo = this.refreshCase(String.valueOf(refreshCaseBatchReqVo.getCreditcaseid()),userId);
            refreshCaseBatchReqVo.setUpdateMthsDay(cmdResVo.getCount());
            refreshCaseBatchReqVo.setUpdateOverdueTotalamt(new BigDecimal(cmdResVo.getKeyId()));
//            refreshCaseBatchReqVo.setUpdatecccdsc(fiCreditcasesMapper.getCccDesc("R"));
        }

        return reqVo;
    }

    @Override
    public CaseDeductionBatchReqVo caseDeductionBatch(CaseDeductionBatchReqVo params, JSysUser user) {

        if(!params.getDeduction()){
            List<Long> idList = params.getList().stream().map(LoanInvoiceDeductionBatchVo::getCreditcaseid).collect(Collectors.toList());

            Long caseCount = fiCreditcasesMapper.selectCount(new QueryWrapper<FiCreditcases>()
                    .in("creditcaseid", idList)
                    .gt("overdue_totalamt", 0)
            );
            if(idList.size()!=caseCount){
                params.setIsOverdue(true);
                return params;
            }
            List<LoanInvoiceDeductionBatchVo> lInvoiceDeductionList = iouLoanInvoiceInfoMapper.getLInvoiceDeductionList(idList);
            params.setIsOverdue(false);
            params.setList(lInvoiceDeductionList);
            return params;
        }

        // 进行扣款
        if(params.getDeduction()){

            for (LoanInvoiceDeductionBatchVo item : params.getList()) {

                if(!item.getIsDeduction()){//忽略不能还款的数据
                    continue;
                }
                // 发起扣款申请
                RepayApplyReqVo reqVo=new RepayApplyReqVo();
                reqVo.setCreditcaseid(item.getCreditcaseid());
                reqVo.setLoanInvoiceId(item.getLoanInvoiceId());
                reqVo.setType("1");
                reqVo.setApplyType(item.getApiId().equals("204")?1:2);//204=融资中台
                reqVo.setCustomernumber(item.getCustomernumber());
                reqVo.setProductId(item.getProductId());
                reqVo.setRepymtAmt1(item.getPayAmt());
                CmdResVo cmdResVo = this.repaymentApply(user,reqVo);
            }

            return params;
        }

        return params;
    }

    @Override
    @Transactional
    public CmdResVo refreshCase(String creditcaseid,String userId) {

        Date currentDate= new Date();

        //获取案件信息
        FiCreditcases dbFiCreditcases = fiCreditcasesMapper.selectJoinOne(FiCreditcases.class,
                new MPJLambdaWrapper<>(FiCreditcases.class)
                        .leftJoin("iou_product ioup on ioup.product_id = t.product_id and ifnull(ioup.merchant_id,'') = ifnull(t.merchant_id,'')")
//                        .leftJoin(IouProduct.class, "ioup",
//                                on->(on.eq(IouProduct::getProductId, FiCreditcases::getProductId)
//                                        .eq(IouProduct::getMerchantId,FiCreditcases::getMerchantId)
////                                        .eq(IouProduct::getProductType,FiCreditcases::getProdtype)
//                                ))
                        .selectAll(FiCreditcases.class)
                        .selectAs("ioup.source", FiCreditcases::getProductSource)
                        .eq(FiCreditcases::getCreditcaseid,creditcaseid)
        );

        if (dbFiCreditcases==null){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        FiCreditcases fiCreditcases=new FiCreditcases();
        fiCreditcases.setCreditcaseid(dbFiCreditcases.getCreditcaseid());
        fiCreditcases.setMddt(currentDate);
        fiCreditcases.setMdusr(userId);
        fiCreditcases.setAccBalLastUpTime(currentDate);

        Integer prouctSource=dbFiCreditcases.getProductSource();

        //获取当前案件逾期借据
        List<IouLoanInvoiceInfo> dbIouLoanInvoiceList = iouLoanInvoiceInfoMapper.selectList(new QueryWrapper<IouLoanInvoiceInfo>()
                .eq("creditcaseid", dbFiCreditcases.getCreditcaseid())
                .eq("loan_invoice_status", "2")
        );

        if(dbIouLoanInvoiceList==null
            || dbIouLoanInvoiceList.size()==0){
            return new CmdResVo(0,fiCreditcases.getCcc());
        }

        BigDecimal overdueTotalamt=new BigDecimal(0);//实时逾期金额
        Integer mthsDay=0;//逾期天数

        //实时刷新借据信息
        String identCrdNo=null;//身份证号
        for (IouLoanInvoiceInfo iouLoanInvoiceInfo : dbIouLoanInvoiceList) {

            /**
             * 借去花产品
             * :HLDJQH01 智慧线上
             * :HLD009 融资中台 --HLD009修改为HLD009001
             */
            if(iouLoanInvoiceInfo.getProductId().equals("HLD009001")){
                prouctSource=1;
            } else if (iouLoanInvoiceInfo.getProductId().equals("HLDJQH01")) {
                prouctSource=2;
            }

            //不等于 借去花产品
            if(prouctSource==1){
                //融资中台
                //获取还款计划 CLMP50
                LineAPIR clmpRepayPlan = onLineApiService.getCLMPRepayPlan(iouLoanInvoiceInfo.getMerchantId(),
                        iouLoanInvoiceInfo.getLoanInvoiceId(),null);//获取该借据下的逾期还款计划
                JSONArray repymtPlnBosArry = clmpRepayPlan.getJsonObject().getJSONArray("RepymtPlnBosArry");

                if(repymtPlnBosArry==null){
                    throw new ServiceException(EnumRCode.NoData.value, EnumRCode.NoData.name);
                }

                if(clmpRepayPlan.getCode()==-1){
                    throw new ServiceException(EnumRCode.OnLineApiError.value, EnumRCode.OnLineApiError.name);
                }

                // 获取 逾期金额 还款计划状态为逾期&& 剩余金额 leftAmt
                for (int i = 0; i < repymtPlnBosArry.size(); i++) {
                    String preRepymtDt = repymtPlnBosArry.getJSONObject(i).get("PreRepymtDt").toString();

                    //校验 还款计划的应还时间  应还日期大于当前时间略过
                    if(dateComparison(preRepymtDt,"1")){
                        continue;
                    }

                    //计算逾期天数
                    Long l = timeDistance(preRepymtDt
                            ,"1");//应还时间|当前时间获取逾期天数
                    BigDecimal remainpay = new BigDecimal(repymtPlnBosArry.getJSONObject(i).get("LftAmt").toString());

                    log.info("remainpay:{}",remainpay);
                    if(remainpay.compareTo(BigDecimal.ZERO)>0){
                        overdueTotalamt=overdueTotalamt.add(remainpay);//剩余金额

                        log.info("overdueTotalamt::{},mthsDay:{},remainpay:{}",overdueTotalamt,l,remainpay);
                        //记录最高逾期天数
                        if(l>mthsDay){
                            mthsDay= Math.toIntExact(l);
                        }
                    }
                }
            }else if (prouctSource==2){
                //智慧线上
                if(identCrdNo==null){
                    //获取客户身份证号
                    ConCustomer dbConCustomer=conCustomerService.getById(dbFiCreditcases.getCustomernumber());
                    identCrdNo=dbConCustomer.getOpenacctcertno();
                }
                //获取还款计划 SOFP004
                LineAPIR sofpRepayPlan = onLineApiService.getSOFPRepayPlan(iouLoanInvoiceInfo.getLoanInvoiceId()
                        , identCrdNo);


                if(sofpRepayPlan.getCode()==-1){
                    throw new ServiceException(EnumRCode.OnLineApiError.value, EnumRCode.OnLineApiError.name);
                }

                JSONArray repymtPlanArry = sofpRepayPlan.getJsonObject().getJSONArray("RepymtPlanArry");
                for (int i = 0; i < repymtPlanArry.size(); i++) {

                    String rpyblDt1 = repymtPlanArry.getJSONObject(i).get("RpyblDt1").toString();
                    //校验 还款计划的应还时间  应还日期大于当前时间略过
                    if(dateComparison(rpyblDt1,"2")){
                        continue;
                    }

                    BigDecimal remainpay = new BigDecimal(repymtPlanArry.getJSONObject(i).get("remainpay").toString());
                    if(remainpay.compareTo(BigDecimal.ZERO)>0){
                        overdueTotalamt=overdueTotalamt.add(remainpay);//剩余金额
                        //计算逾期天数
                        Long l = timeDistance(rpyblDt1,"2");//应还时间|当前时间获取逾期天数
                        //记录最高逾期天数
                        if(l>mthsDay){
                            mthsDay= Math.toIntExact(l);
                        }
                    }
                }
            }
        }


        // 更新案件信息
        fiCreditcases.setOverdueTotalamt(overdueTotalamt);
        fiCreditcases.setMthsDay(mthsDay);
//        fiCreditcases.setCcc(dbFiCreditcases.getCcc());
        fiCreditcasesMapper.updateById(fiCreditcases);
//      手工刷新发现出催,不醉处理.
//        //案件出催 校验 逾期金额==0
//        if(overdueTotalamt.equals(BigDecimal.ZERO)){
//
//
//            //进行出催操作
//            fiCreditcases.setCcc(EnumFiCaseQueue.R.value);//队列状态 最后一个节点 结清状态
//            fiCreditcases.setStatus(EnumFiCaseStatus.Finish.value);//案件状态
//            fiCreditcases.setStatusdt(currentDate);
//            fiCreditcases.setClosedt(currentDate);
//            fiCreditcasesMapper.updateById(fiCreditcases);
//
//            //记录hist信息
//            toR(currentDate,dbIouLoanInvoiceList,dbFiCreditcases);
//
//            //获取当前案件是否存在正常的借据
////            List<IouLoanInvoiceInfo> dbNormalIouLoanInvoiceList = iouLoanInvoiceInfoMapper.selectList(new QueryWrapper<IouLoanInvoiceInfo>()
////                    .eq("creditcaseid", dbFiCreditcases.getCreditcaseid())
////                    .eq("loan_invoice_status", "1")
////            );
////
////            if(dbNormalIouLoanInvoiceList!=null
////                    && dbNormalIouLoanInvoiceList.size()>0){
////                return new CmdResVo(1,fiCreditcases.getCcc());
////            }else {
////                //进行出催操作
////                fiCreditcases.setCcc(EnumFiCaseQueue.R.value);//队列状态 最后一个节点 结清状态
////                fiCreditcases.setStatus(EnumFiCaseStatus.Finish.value);//案件状态
////                fiCreditcases.setStatusdt(currentDate);
////                fiCreditcases.setClosedt(currentDate);
////                fiCreditcasesMapper.updateById(fiCreditcases);
////
////                //记录hist信息
////                toR(currentDate,dbIouLoanInvoiceList,dbFiCreditcases);
////            }
//
//        }
        return new CmdResVo(mthsDay,overdueTotalamt.toString());
    }



    //记录hist 信息
    public void toR(Date currentDate,List<IouLoanInvoiceInfo> dbIouLoanInvoiceInfo,FiCreditcases fiCreditcases) {

        // 逻辑待补充...借据信息要不要记录|案件hist要不要记录 | 还是等第二天跑批的时候记录

        // 更新hist 信息
//        FiCreditcases dbFiCreditcases = f.selectById(dbIouLoanInvoiceInfo.getCreditcaseid());
        FiCreditcasesHist fiCreditcasesHist=new FiCreditcasesHist();
        BeanUtils.copyProperties(fiCreditcases,fiCreditcasesHist);
        fiCreditcasesHist.setActiontype(4);//出催标识
        fiCreditcasesHistService.save(fiCreditcasesHist);
    }


    //计算时间差
    public static long timeDistance(String date,String type){
        SimpleDateFormat formatter = null;
        if("1".equals(type)){
            formatter= new SimpleDateFormat("yyyy-MM-dd");
        }else if("2".equals(type)){
            formatter= new SimpleDateFormat("yyyy/MM/dd");
        }

        Date parse = null;
        try {
            parse = formatter.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        LocalDate localInputDate = parse.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        return ChronoUnit.DAYS.between(localInputDate, currentDate);
    }

    public static Boolean dateComparison(String date,String type){
        SimpleDateFormat formatter = null;
        if("1".equals(type)){
            formatter= new SimpleDateFormat("yyyy-MM-dd");
        }else if("2".equals(type)){
            formatter= new SimpleDateFormat("yyyy/MM/dd");
        }
        Date parse = null;
        try {
            parse = formatter.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        // 获取当前日期
        Date currentDate = new Date();

        // 比较当前日期和指定日期
        if (currentDate.after(parse)) {
//            System.out.println("当前日期大于指定日期");
            return false;//跳过 大于当前日期的
        } else {
//            System.out.println("当前日期不大于指定日期");
            return true;
        }

    }


    @Override
    public LineAPIR getCLMPLoanLnvoiceInfo(CLMPReqVo reqVo) {
//        if(JPubUtils.IsEmpty(reqVo.getMrchId())
//                ||JPubUtils.IsEmpty(reqVo.getCustomernumber())){
//            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
//        }

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }


        return onLineApiService.getCLMPLoanLnvoiceInfo(null
                ,dbConCustomer.getOpenacctcertno()
                ,dbConCustomer.getOpenacctcerttype(),null,reqVo.getStatus(),null);
    }

    @Override
    public LineAPIR getCLMPRepayPlan(CLMPReqVo reqVo) {
        if(JPubUtils.IsEmpty(reqVo.getDblNo())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        return onLineApiService.getCLMPRepayPlan(null
                ,reqVo.getDblNo(),null);
    }

    @Override
    public LineAPIR getCLMPRepaySerial(CLMPReqVo reqVo) {
        if(JPubUtils.IsEmpty(reqVo.getDblNo())
                ||JPubUtils.IsEmpty(reqVo.getCustomernumber())
                ||JPubUtils.IsEmpty(reqVo.getProductId())
        ){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        List<IouProduct> productList = iouProductService.query()
                .eq("product_id", reqVo.getProductId()).list();

        if(productList!=null && productList.size()>0){
            if(JPubUtils.IsNotEmpty(productList.get(0).getParentId())){
                log.info("parentId:{}",productList.get(0).getParentId());
                reqVo.setProductId(productList.get(0).getParentId());
            }
        }


        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        return onLineApiService.getCLMPRepaySerial(reqVo.getPageNum(),reqVo.getPageSize(),null
                ,dbConCustomer.getOpenacctcertno(),
                dbConCustomer.getOpenacctcerttype(),
                reqVo.getDblNo(),
                reqVo.getProductId());
    }

    @Override
    public LineAPIR getCLMPRepaymentResult(CLMPReqVo reqVo) {
//        if(JPubUtils.IsEmpty(reqVo.getMrchId())
//        ){
//            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
//        }

        //获取借据还款信息
//
//        return onLineApiService.getCLMPRepaymentResult(reqVo.getMrchId(),
//                null);
        return null;//废弃
    }

    @Override
    public LineAPIR refreshCLMPCreditLimit(CLMPReqVo reqVo) {
        if(JPubUtils.IsEmpty(reqVo.getCustomernumber())
                ||JPubUtils.IsEmpty(reqVo.getProductId())
        ){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        List<IouProduct> productList = iouProductService.query()
                .eq("product_id", reqVo.getProductId()).list();

        if(productList!=null && productList.size()>0){
            if(JPubUtils.IsNotEmpty(productList.get(0).getParentId())){
                log.info("parentId:{}",productList.get(0).getParentId());
                reqVo.setProductId(productList.get(0).getParentId());
            }
        }

        //获取 客户证件号
        ConCustomer dbConCustomer=conCustomerService.getById(reqVo.getCustomernumber());
        if(dbConCustomer==null
                || JPubUtils.IsEmpty(dbConCustomer.getOpenacctcertno())){
            throw new ServiceException(EnumRCode.ArgErr.value, EnumRCode.ArgErr.name);
        }

        return onLineApiService.refreshCLMPCreditLimit(null
                ,dbConCustomer.getOpenacctcertno(),
                dbConCustomer.getOpenacctcerttype(),
                reqVo.getProductId());
    }
}
